package cn.wygandwdn.core.spring;

import cn.wygandwdn.core.annotation.RpcService;
import cn.wygandwdn.core.annotation.ServiceScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.StandardAnnotationMetadata;

/**
 * @description:
 * @author: WYG
 * @time: 2021/10/29 20:59
 */

public class CustomScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
    private static final Logger log = LoggerFactory.getLogger(CustomScannerRegistrar.class);


    private static final String BASE_PACKAGE_ATTRIBUTE_NAME = "basePackages";
    private ResourceLoader resourceLoader;


    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        // 提前注册SpringBeanPostProcessor,这样才能在注册服务时对其执行BeanPostProcessor的方法
        BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(SpringBeanPostProcessor.class).getBeanDefinition();
        registry.registerBeanDefinition("springBeanPostProcessor", beanDefinition);

        AnnotationAttributes annotationAttributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(ServiceScan.class.getName()));
        String[] scanBasePackage = new String[0];
        if (annotationAttributes != null) {
            annotationAttributes.getStringArray(BASE_PACKAGE_ATTRIBUTE_NAME);
        }
        if (scanBasePackage.length == 0) {
            // 获取该注解注释的类对应的包名
            scanBasePackage = new String[] {((StandardAnnotationMetadata) metadata).getIntrospectedClass().getPackage().getName()};
        }
        // 扫描RpcService注解配置的类
        CustomScanner serviceScanner = new CustomScanner(registry, RpcService.class);
        if (resourceLoader != null) {
            serviceScanner.setResourceLoader(resourceLoader);
        }
        int serviceCount = serviceScanner.scan(scanBasePackage);
        log.debug("serviceScanner扫描到的服务数量 [{}]", serviceCount);
    }
}
